package com.xpm.base;

import android.annotation.SuppressLint;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;

import java.util.ArrayList;
import java.util.List;

/**
 * BaseAdapter，用于快速绑定实体与视图
 * @param <T>
 * @param <VB>
 */
public abstract class BaseAdapter<T,VB extends ViewBinding> extends RecyclerView.Adapter<BaseAdapter.BaseViewHolder<VB>>{
    protected List<T> dataList = new ArrayList<>();
    protected OnItemClickListener<T> itemClickListener;
    private OnItemLongClickListener<T> itemLongClickListener;


    /**
     * 设置新数据
     * 关于 notifyDataSetChanged()
     * 1. @SuppressLint("NotifyDataSetChanged") 的作用
     * @SuppressLint("NotifyDataSetChanged") 是一个注解，用于抑制特定的 Lint 警告。在这个上下文中，NotifyDataSetChanged 警告通常是由于使用 notifyDataSetChanged() 方法引起的。
     * notifyDataSetChanged() 方法会刷新整个适配器的数据集，这可能会导致性能问题，尤其是在数据量较大或频繁更新的情况下。Lint 工具会提示开发者考虑使用更高效的方法来更新数据，例如 notifyItemInserted()、notifyItemRemoved()、notifyItemChanged() 等，这些方法可以更精确地更新数据集中的特定项，从而提高性能。
     * 2. 使用建议
     * 虽然 @SuppressLint("NotifyDataSetChanged") 可以抑制警告，但更好的做法是尽量避免使用 notifyDataSetChanged()，而是使用更细粒度的更新方法。以下是一些替代方案：
     * notifyItemInserted(int position)：在指定位置插入一个新项。
     * notifyItemRemoved(int position)：移除指定位置的项。
     * notifyItemChanged(int position)：更新指定位置的项。
     * notifyItemRangeInserted(int positionStart, int itemCount)：在指定位置插入多个新项。
     * notifyItemRangeRemoved(int positionStart, int itemCount)：移除指定位置的多个项。
     * notifyItemRangeChanged(int positionStart, int itemCount)：更新指定位置的多个项。
      */
    @SuppressLint("NotifyDataSetChanged")
    public void setData(List<T> newData) {
        dataList.clear();
        dataList.addAll(newData);
        notifyDataSetChanged();  // 如果数据量较大，考虑使用更细粒度的更新方法
    }
    // 添加更多数据
    public void addData(List<T> newData) {
        int startPosition = dataList.size();
        dataList.addAll(newData);
        notifyItemRangeInserted(startPosition, newData.size());
    }
    @Override
    public int getItemCount() {
        return dataList == null? 0 : dataList.size();
    }
    @NonNull
    @Override
    public BaseViewHolder<VB> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        VB binding = createBinding(inflater, parent);
        return new BaseViewHolder<>(binding);
    }

    @Override
    public void onBindViewHolder(@NonNull BaseViewHolder<VB> holder, int position) {
        T item = dataList.get(position);
        bindView(holder.binding, item, position);
        holder.itemView.setOnClickListener(v -> {
            if (itemClickListener != null) {
                itemClickListener.onItemClick(item, position);
            }
        });
        holder.itemView.setOnLongClickListener(v -> {
            if (itemLongClickListener != null) {
                return itemLongClickListener.onItemLongClick(item, position);
            }
            return false;
        });
    }
    // 创建 ViewBinding 的抽象方法
    protected abstract VB createBinding(LayoutInflater inflater, ViewGroup parent);

    // 绑定数据的抽象方法
    protected abstract void bindView(VB binding, T item, int position);

    // 点击事件接口
    public interface OnItemClickListener<T> {
        void onItemClick(T item, int position);
    }

    public void setOnItemClickListener(OnItemClickListener<T> listener) {
        this.itemClickListener = listener;
    }
    public interface OnItemLongClickListener<T> {
        boolean onItemLongClick(T item, int position);
    }
    public void setOnItemLongClickListener(OnItemLongClickListener<T> listener) {
        this.itemLongClickListener = listener;
    }


    // 基础 ViewHolder
    public static class BaseViewHolder<VB extends ViewBinding> extends RecyclerView.ViewHolder {
        final VB binding;
        BaseViewHolder(VB binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }
}
